/*
 * Поиск цикла
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

#ifdef DEBUG
# define debug_fprintf(x)	fprintf x
#else
# define debug_fprintf(x)	while(0)
#endif

/* {{{ autoarray */
struct vector {
	int *data;
	int n;
	int max;
};

/* {{{ functions */
void
vector_init(struct vector *v, int p)
{
	if (p < 0)
		p = 0;
	v->max = 1 << p;
	v->n = 0;
	v->data = (int *) calloc((size_t) v->max, sizeof *v->data);
}

int
vector_append(struct vector *v, int a)
{
	int *t;

	if (v->max == 0)
		vector_init(v, 0);

	if (v->n + 1 > v->max) {
		t = (int *) realloc(v->data, sizeof *t * (v->max *= 2));
		if (!t) {
			fprintf(stderr, "vector_append(): failed to allocate %d bytes\n", v->max);
			return 1;
		} else {
			v->data = t;
		}
	}

	v->data[v->n++] = a;

	return 0;
}

int
vector_sort(struct vector *v, int (*cmpf)(const void *, const void *))
{
	if (v->max > 0 && v->n > 1) {
		qsort(v->data, (size_t) v->n, sizeof *v->data, cmpf);
		return 0;
	} else {
		return 1;
	}
}

int
vector_cleanup(struct vector *v)
{
	if (v->max > 0) {
		v->max = v->n = 0;
		free(v->data);
		v->data = NULL;
		return 0;
	} else {
		return 1;
	}
}
/* }}} */
/* }}} */

/* {{{ doubly-linked list */
struct dll_node {
	int key;
	struct dll_node *prev, *next;
};

/* {{{ functions */
/*
 * This function inserts one node pointed to by 'ins' _after_ 'node'.
 * And it doesn't give a rat's ass about anything else.
 */
struct dll_node *
dll_insert(struct dll_node *node, struct dll_node *ins)
{
	assert(node != NULL);
	if (ins == NULL) {
		fprintf(stderr, "dll_insert(): ins is NULL, not doing anything\n");
		return node;
	}

	if (node->next) {
		assert(node->next->prev == node);
		node->next->prev = ins;
	}
	ins->next = node->next;
	ins->prev = node;
	node->next = ins;
	return ins;
}

/*
 * This function extracts 'node' from a doubly-linked list and returns pointer
 * to that node, which pointers '->prev' and '->next' are not reset.
 *
 * If you really want to get rid of a node, call
 * 	free(dll_delete(unneeded_node));
 */
struct dll_node *
dll_delete(struct dll_node *node)
{
	if (!node) {
		fprintf(stderr, "dll_delete(): received NULL ptr, wtf am i supposed to delete?\n");
		return NULL;
	}
	if (node->prev) {
		assert(node->prev->next == node);
		node->prev->next = node->next;
	}
	if (node->next) {
		assert(node->next->prev == node);
		node->next->prev = node->prev;
	}
	return node;
}
/* }}} */
/* }}} */

/* {{{ graph repr: adjlist w/ doubly-linked list */
enum vertex_st {
	VTX_ST_UNKN = 0,
	VTX_ST_OPEN,
	VTX_ST_VISITED
};

struct adjlist_dll {
	struct dll_node *head;
	struct dll_node *tail;
	int _list_len;

	enum vertex_st state;
	int color;
	int distance;
	int prev;
};
/* {{{ functions */
void
adjl_dll_connect(struct adjlist_dll *node, int conid)
{
	struct dll_node *wanderer;

	wanderer = (struct dll_node *) malloc(sizeof *wanderer);
	wanderer->key = conid;
	wanderer->prev = wanderer->next = NULL;

	if (node->head == NULL) {
		assert(node->tail == NULL);
		node->head = node->tail = wanderer;
		node->_list_len = 1;
	} else {
		dll_insert(node->tail, wanderer);
		node->_list_len++;
	}
}

void
adjl_dll_cleanup(struct adjlist_dll *al)
{
	struct dll_node *nx = al->head, *pr = al->head;

	while (nx) {
		pr = nx;
		nx = nx->next;
		free(pr);
	}
	al->_list_len = 0;
}
/* }}} */
/* }}} */

int
dfs_find_cycle(struct adjlist_dll *al, const int idx, struct vector *cycle)
{
	struct dll_node *nd = al[idx].head;
	int ret = 0;

	al[idx].state = VTX_ST_OPEN;
	while (nd) {
		if (al[nd->key].state == VTX_ST_UNKN) {
			ret = dfs_find_cycle(al, nd->key, cycle);
			if (ret == 1) {
				/* a single typo in 'rm' command can really ruin your day :-( */
				vector_append(cycle, idx);
				if (al[idx].color == 1)
					return 2; /* stop adding nodes to path */
				else
					return 1;
			} else if (ret == 2) {
				return 2;
			}
		} else if (al[nd->key].state == VTX_ST_OPEN) {
			/* discovered a cycle.
			 * now we need to start filling out the path */
			al[nd->key].color = 1; /* so that we know when we need to stop */
			vector_append(cycle, idx);
			return 1;
		}
		nd = nd->next;
	}
	al[idx].state = VTX_ST_VISITED;
	return 0;
}

int
main(int argc, char **argv)
{
	struct adjlist_dll *al;
	int i, n, m, a, b;
	struct vector cycle;

	scanf("%d%d", &n, &m);
	al = (adjlist_dll *) calloc(n, sizeof *al);
	cycle.max = 0;
	vector_init(&cycle, 6);
	for (i = 0; i < m; i++) {
		scanf("%d%d", &a, &b);
		--a,--b;
		adjl_dll_connect(al + a, b);
	}

	for (i = 0; i < n; i++) {
		if (al[i].state == VTX_ST_UNKN &&
				dfs_find_cycle(al, i, &cycle) > 0) {
			//printf("%d\n", cycle.n);
			puts("YES");
			for (int j = cycle.n - 1; j >= 0; j--) {
				printf("%d ", cycle.data[j] + 1);
			}
			fputc('\n', stdout);
			break;
		}
	}
	if (cycle.n == 0)
		puts("NO");

	for (i = 0; i < n; i++)
		adjl_dll_cleanup(al + i);
	free(al);
	vector_cleanup(&cycle);
	return 0;
}
